package com.wframe.project.jnd.wx.filter;

import com.wframe.project.jnd.rest.util.*;
import com.wframe.project.jnd.util.WebUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.regex.Pattern;

/**
 * Created by lwb on 2017/4/27.
 */
@Component("sessionFilter")
public class WechatSessionFilter extends OncePerRequestFilter {

    private String exclude;  //不需要过滤的路径集合
    private Pattern pattern;  //匹配不需要过滤路径的正则表达式

    public void setExclude(String exclude) {
        this.exclude = exclude;
        pattern = Pattern.compile(getRegStr(exclude));
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (pattern.matcher(request.getRequestURI()).matches()) {
            filterChain.doFilter(request, response);
        } else {
            if (checkNotLogin(request.getSession())) {
                if (checkRequest(request)) {
                    response.sendRedirect("/we/user/login");
                } else {
                    WebUtils.responseWrite(response, new JsonReturn().toErrorString(getClass(), new ClientException(CodeEnum.LoginOut)));
                }
            } else {
                filterChain.doFilter(request, response);
            }
        }
    }

    /**
     * 非AJAX请求
     *
     * @param request
     * @return true：满足，false：不满足
     */
    private boolean checkRequest(HttpServletRequest request) {
        boolean checkResult = false;

        String requestType = request.getHeader("X-Requested-With");
        if (requestType == null || (!"XMLHttpRequest".equalsIgnoreCase(requestType))) {
            //非AJAX请求
            checkResult = true;
        }

        return checkResult;
    }

    /**
     * 检查用户是否已经登录
     *
     * @param session
     * @return true：已登录，false：未登录
     */
    private boolean checkNotLogin(HttpSession session) {
        SessionUser sessionUser = WebSession.getWbUser(session);
        if (sessionUser != null && StringUtils.isNotEmpty(sessionUser.getUserid())) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 将传递进来的不需要过滤得路径集合的字符串格式化成一系列的正则规则
     *
     * @param str 不需要过滤的路径集合
     * @return 正则表达式规则
     */
    private String getRegStr(String str) {
        if (StringUtils.isNotBlank(str)) {
            String[] excludes = str.split(",");  //以逗号进行分割
            int length = excludes.length;
            for (int i = 0; i < length; i++) {
                String tmpExclude = excludes[i];
                //对换行符、点、反斜杠和星号进行转义
                tmpExclude = tmpExclude.replace(File.separator, "").replace("\\", "\\\\").replace("*", "");
                tmpExclude = "^\\S*" + StringUtils.trimToEmpty(tmpExclude) + "\\S*$";
                excludes[i] = tmpExclude;
            }
            return StringUtils.join(excludes, "|");
        }
        return str;
    }

}
